package com.ioc;

import com.ioc.autowried.Cup;
import com.ioc.autowried.person;
import com.ioc.config.AwareConfig;
import com.ioc.config.Beanfig;
import com.ioc.config.MyConfigAutowried;
import com.ioc.config.ProfileConfig;
import com.ioc.conver.ConverCofig;
import com.ioc.conver.StringToDate;
import com.ioc.pojo.User;
import com.ioc.service.serviceimpl.impl;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import java.util.Date;

/**
 * Created by win10 on 2020/2/8 13:46
 * @author Administrator
 */
public class text {

    @Test
    public void ConverConfig() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConverCofig.class);
        StringToDate stringToDate = context.getBean(StringToDate.class);
        Date convert = stringToDate.convert("2020-10-11");
        System.out.println(convert);
    }


    /**
     * 使用 profile 注解指定启动的环境
     * public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
     * this();
     * this.register(annotatedClasses);
     * this.refresh();
     * }
     */
    @Test
    public void profileConfig() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        //1、设置环境
        context.getEnvironment().setActiveProfiles("dev");
        //2、加载住配置类
        context.register(ProfileConfig.class);
        // 3、刷新容器
        context.refresh();
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println("ioc = > " + name);
        }
    }

    /**
     * ApplicationContextAware, BeanNameAware
     * <p>
     * 导入底层的bean
     */
    @Test
    public void awareConfig() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AwareConfig.class);
        String[] names = context.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println("ioc = > " + name);
        }

        System.out.println("context = > " + context);
    }

    /**
     * @Autowired 1、可以添加在字段上面
     * 2、可以添加在 get  和构造器上面
     * 3、可以添加在方法的参数上面
     * 3、也可以只提供 get 和构造器 也是能够实现自动注入
     * 4、自动注入属性都是从 ioc 容器中获取的
     */
    @Test
    public void autowriedTest() {
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(MyConfigAutowried.class);
        System.out.println("ioc 容器创建完毕");
        String[] beanNames = actx.getBeanDefinitionNames();
        for (String name : beanNames) {
            System.out.println(name);
        }
        person bean = actx.getBean(person.class);

        System.out.println(bean);

        Cup cupBean = actx.getBean(Cup.class);
        System.out.println(cupBean);
    }

    @Test
    public void autowried2Test() {
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(MyConfigAutowried.class);
        System.out.println("ioc 容器创建完毕");
        String[] beanNames = actx.getBeanDefinitionNames();
        for (String name : beanNames) {
            System.out.println(name);
        }
        Object userDao = actx.getBean("userDao");

        System.out.println(userDao);
        impl impl = (com.ioc.service.serviceimpl.impl) actx.getBean("impl");
        impl.printf();
    }

    /**
     * @PostConstruct 在创建bean 并且属性赋值完成之后调用。
     * @PreDestroy 在容器销毁之前通知处理一些事务。
     */
    @Test
    public void test4() {
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(Beanfig.class);
        System.out.println("ioc 容器创建完毕");
        String[] beanNames = actx.getBeanDefinitionNames();
        for (String name : beanNames) {
            System.out.println(name);
        }
        actx.destroy();
        System.out.println("ioc 容器销毁");
    }

    /**
     * 1、包扫描  + 注解
     * 2、@bean
     * 3、@import
     * 默认的 id就是全类名
     * 4、ImportBeanDefinitionRegistrar
     * 5、ImportSelector
     * 6、FactoryBean
     */
    @Test
    public void test3() {
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(Beanfig.class);
        System.out.println("ioc 容器创建完毕");
        String[] beanNames = actx.getBeanDefinitionNames();
        for (String name : beanNames) {
            System.out.println(name);
        }
        Object factory = actx.getBean("colorFactory");
        Object factory1 = actx.getBean("colorFactory");
        System.out.println(factory == factory1);
        System.out.println(factory.getClass());

        Object actxBean = actx.getBean("&colorFactory");
        System.out.println(actxBean.getClass());
    }

    @Test
    public void test2() {
        /**
         * @Target({ElementType.TYPE, ElementType.METHOD})
         * @Retention(RetentionPolicy.RUNTIME)
         * @Documented
         * public @interface Conditional {
         *
         * }
         * 按照条件导入 bean, 可以添加在方法和类上面
         *
         */
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(Beanfig.class);
        System.out.println("ioc 容器创建完毕");
        ConfigurableEnvironment environment = actx.getEnvironment();
        String OsName = environment.getProperty("os.name");
        System.out.println(OsName);
        /**
         * 得到 所有User 类型的bean
         */
        String[] names = actx.getBeanNamesForType(User.class);
        for (String name : names) {
            System.out.println(name);
        }
    }

    /**
     * 测试 类 1
     *
     * @Scope("prototype") 单例下：
     * 在容器创建的时候就会会初始化bean
     * 多例下：
     * 创建容器后并不会初始化bean, 只有在获得bean的时候才会初始化
     * @Lazy 懒加载： 只有调用该类的时候才会初始化 bean
     */
    @Test
    public void test1() {
        AnnotationConfigApplicationContext actx = new AnnotationConfigApplicationContext(Beanfig.class);
        System.out.println("ioc 容器创建完毕");
        String[] names = actx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        Object user = actx.getBean("user");
        Object user1 = actx.getBean("user");
        System.out.println(user == user1);
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(Beanfig.class);
        String[] names = configApplicationContext.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(" -  > " + name);
        }

        configApplicationContext.destroy();
    }
}
